package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.domain.db.*;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.RecommendUser;
import com.itheima.domain.mongo.Sound;
import com.itheima.domain.mongo.Visitor;
import com.itheima.domain.vo.*;
import com.itheima.service.db.*;
import com.itheima.service.mongo.*;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class MakeFriendManager {

    @Reference
    private RecommendUserService recommendUserService;
    @Reference
    private UserInfoService userInfoService;
    /**
     * 今日佳人
     * @return
     */
    public RecommendUserVo todayBest() {
        //1.获得当前登录的用户id
        Long loginUserId = UserHolder.getId();
        //2.根据id查询推荐的用户id
        RecommendUser recommendUser = recommendUserService.findBestUser( loginUserId );

        //3.转换vo对象
        RecommendUserVo vo = new RecommendUserVo();
        //3.1 查询用户信息
        UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());
        //3.2 封装数据
        vo.setUserInfo(userInfo);
        vo.setFateValue( recommendUser.getScore().longValue() );
        return vo;
    }

    /**
     * 推荐列表
     * @param page
     * @param pageSize
     * @return
     */
    public PageBeanVo findRecommendUserList(Integer page, Integer pageSize) {
        //1.获得当前登录人
        Long loginUserId = UserHolder.getId();
        //2.根据登录人查询到推荐用户列表集合
        PageBeanVo pageBeanVo = recommendUserService.findRecommendUserList(page , pageSize ,loginUserId );

        List<RecommendUser> items = (List<RecommendUser>) pageBeanVo.getItems();
        List<RecommendUserVo> voList = new ArrayList<>();

        /*if(CollectionUtil.isEmpty(items)){//集合为空 构建假数据

        }*/

        //3.构建返回vo
        for (RecommendUser recommendUser : items) {
            //3.1 创建vo对象
            RecommendUserVo vo = new RecommendUserVo();
            //查询用户信息
            UserInfo userInfo = userInfoService.findById(recommendUser.getUserId());
            //3.2 封装数据
            vo.setUserInfo( userInfo );
            //3.3. 缘分值
            vo.setFateValue( recommendUser.getScore().longValue()  );
            voList.add(vo);
        }

        //4.构建pageBean
        pageBeanVo.setItems( voList );

        System.out.println(pageBeanVo);
        //5.返回数据
        return pageBeanVo;
    }

    /**
     * 查询推荐用户的详情
     * @param recommendUserId
     * @return
     */
    public RecommendUserVo findRecommendUserById(Long recommendUserId) {
        //1.获得当前登录人id
        Long loginUserId = UserHolder.getId();
        //2.查询推荐用户的个人信息
        UserInfo userInfo = userInfoService.findById(recommendUserId);

        //3.查询缘分值
        RecommendUser recommendUser = recommendUserService.findFateValue(loginUserId , recommendUserId);
        //4.返回vo
        RecommendUserVo vo = new RecommendUserVo();
        vo.setUserInfo(userInfo);
        vo.setFateValue(  recommendUser.getScore().longValue() );//缘分值
        return vo;
    }


    @Reference
    private QuestionService questionService;
    /**
     * 查询问题数据
     * @param userId
     * @return
     */
    public String findQuestionByUserId(Long userId) {
        //1.根据id查询问题对象
        Question question = questionService.findByUid(userId);
        if(question == null){//如果为空给默认数据
            return "你喜欢高山还是流水?";
        }
        //2.返回数据
        return question.getStrangerQuestion();
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Reference
    private VisitorService visitorService;
    /**
     * 查看最近访客
     * 1.查看redis中是否有上次登录的时间
     * 2.如果没有 直接返回空数据即可
     * 3.如果有, 获得当前登录人的id  查询访客表数据  返回List<Visitors>
     * 4.创建 List<VisitorVo> 对象返回数据
     * 4.1 查询用户数据
     * 4.2 查询缘分值
     * @return
     */
    public List<VisitorVo> findVisitors() {
        Long loginUserId = UserHolder.getId();
        //1.查看redis中是否有上次登录的时间
        String lastTime = stringRedisTemplate.opsForValue().get(ConstantUtil.LAST_ACCESS_TIME + loginUserId);
        //2.如果没有 直接返回空数据即可
        if(StrUtil.isEmpty(lastTime)){
            System.out.println("没有最后一次登录时间 返回数据为空");
            //要存入当前时间
            stringRedisTemplate.opsForValue().set(ConstantUtil.LAST_ACCESS_TIME + loginUserId , System.currentTimeMillis()+"" );
            return null;
        }
        //3.如果有, 获得当前登录人的id  查询访客表数据  返回List<Visitors>
        List<Visitor> visitorList = visitorService.findVisitorList(loginUserId , lastTime );
        //4.创建 List<VisitorVo> 对象返回数据
        List<VisitorVo> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(visitorList)){
            for (Visitor visitor : visitorList) {
                VisitorVo vo = new VisitorVo();
                //4.1 查询用户数据
                UserInfo userInfo = userInfoService.findById(visitor.getVisitorUserId());
                //4.2 查询缘分值 不一定能查询到数据 在代码已经构建过假数据
                RecommendUser recommendUser = recommendUserService.findFateValue(loginUserId, visitor.getVisitorUserId());
                vo.setUserInfo(userInfo);
                vo.setFateValue(recommendUser.getScore().longValue());
                voList.add(vo);
            }

        }

        return voList;
    }


    @Reference
    private UserLocationService userLocationService;
    /**
     * 保存或者更新 实时位置 (准实时)
     * @param latitude
     * @param longitude
     * @param addrStr
     */
    public void saveOrUpdateUserLocation(String latitude, String longitude, String addrStr) {
        //保存某个人的实时位置
        userLocationService.save(latitude ,longitude ,addrStr , UserHolder.getId() );
    }

    /**
     * 查看附近的人
     * 1.获得当前登录的用户id
     * 2.根据半径和用户id查询 附近人的数据 返回值是一个id的列表 此处不允许返回UserLocation对象
     * 3.判断id是否为空 -> 为空返回空数据
     * 4.如果不为空 遍历
     * 5.根据这些id 查询userInfo的信息 (跳过自己) 判断性别
     * 6.组装vo返回
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> findNearUser(String gender, String distance) {
        //1.获得当前登录的用户id
        Long loginUserId = UserHolder.getId();
        //2.根据半径和用户id查询 附近人的数据 返回值是一个id的列表 此处不允许返回UserLocation对象
        List<Long> ids = userLocationService.findNearUser(loginUserId , distance);
        //3.判断id是否为空 -> 为空返回空数据
        if(CollectionUtil.isEmpty(ids)){
            System.out.println("您附近没有人");
            return null;
        }
        List<NearUserVo> voList = new ArrayList<>();
        //4.如果不为空 遍历
        for (Long id : ids) {
            //5.根据这些id 查询userInfo的信息 (跳过自己) 判断性别
            if(id == loginUserId){//排除自己
                continue;//继续下次循环
            }
            //根据这些id 查询userInfo的信息
            UserInfo userInfo = userInfoService.findById(id);
            //判断性别
            if(!gender.equals(userInfo.getGender())){
                continue; //如果性别不一致 跳过此次循环
            }
            //封装数据
            NearUserVo vo = new NearUserVo();
            BeanUtil.copyProperties(userInfo , vo);
            voList.add(vo);
        }

        //6.组装vo返回
        return voList;
    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;
    /**
     * 发送环信的消息
     * {
     * 	"userId": "1",--------登录用户id
     * 	"nickname": "黑马小妹1",---登录用户昵称
     * 	"strangerQuestion": "你喜欢去看蔚蓝的大海还是去爬巍峨的高山?",----佳人的陌生人问题
     * 	"reply": "我喜欢秋天的落叶，夏天的泉水，冬天的雪地，只要有你一切皆可~"-----你的回答
     * }
     * @param userId
     * @param reply
     */
    public void sendHuanxinMsg(String userId, String reply) {
        //1.获得id
        Long loginUserId = UserHolder.getId();
        //2.根据id查询用户的信息
        UserInfo userInfo = userInfoService.findById(loginUserId);
        //3.查询问题
        Question question = questionService.findByUid(Long.valueOf(userId));
        String questionStr = "";
        if(question == null){
            questionStr = "你喜欢高山还是流水?"; //默认问题
        }else{
            questionStr = question.getStrangerQuestion();
        }

        //4.数据准备
        Map map = new HashMap<>();
        map.put("userId" , loginUserId+""); //此处的userId必须是string类型的
        map.put("nickname" , userInfo.getNickname());
        map.put("strangerQuestion" , questionStr);
        map.put("reply" , reply);

        //将map转换成json
        String json = JSON.toJSONString(map);
        //5.发送数据
        //参数1: 发送给谁  参数2: 发送的内容
        huanXinTemplate.sendMsg(userId , json );
    }


    @Reference
    private FriendService friendService;
    /**
     * 添加联系人
     * @param friendId
     */
    public void addContacts(String friendId) {
        Long loginUserId = UserHolder.getId();//当前登录人id
        //1.添加mongo好友
        friendService.addContacts(loginUserId ,  Long.valueOf(friendId));
        //2.添加环信好友
        huanXinTemplate.addContacts(loginUserId , Long.valueOf(friendId) );
    }

    /**
     * 查询联系人列表
     * @param page
     * @param pageSize
     * @return
     */
    public PageBeanVo findContactList(Integer page, Integer pageSize) {
        //1.分页查询数据  Query query = new Query( where(userId).is(99))
        PageBeanVo pageBeanVo = friendService.findContactList(page, pageSize ,UserHolder.getId());
        //2.获得ids集合
        List<Friend> items = (List<Friend>) pageBeanVo.getItems();
        List<ContactVo> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(items)){
            //3.转换数据
            for (Friend friend : items) {
                //3.1 查询出好友的相关信息
                UserInfo userInfo = userInfoService.findById(friend.getFriendId());
                //3.2 封装vo对象
                ContactVo vo = new ContactVo();
                vo.setUserInfo(userInfo);
                vo.setUserId( friend.getFriendId()+"" ); //好友的id
                voList.add(vo);
            }
        }
        //4.赋值返回
        pageBeanVo.setItems(voList);
        return pageBeanVo;
    }

    @Reference
    private QuestionnaireService questionnaireService;

    @Reference
    private SoulQuestionService soulQuestionService;

    @Reference
    private SoulQuestionOptionService soulQuestionOptionService;

    @Reference
    private QuestionUserLockService questionUserLockService;

    @Reference
    private QuestionnaireReportService questionnaireReportService;

    //测灵魂-问卷列表
    public List<QuestionnaireVo> findTestSoul() {
        Long userId = UserHolder.getId();

        List<QuestionnaireVo> questionnaireVos = new ArrayList<>();
        //查找全部问卷
        List<Questionnaire> questionnaireList = questionnaireService.findQuestionnaire();

        if (CollectionUtil.isNotEmpty(questionnaireList)) {
            for (Questionnaire questionnaire : questionnaireList) {
                QuestionnaireVo questionnaireVo = new QuestionnaireVo();

                //存放所有问题包括了选项
                List<SoulQuestionVo> questions = new ArrayList<>();
                //根据问卷id查找所有问题
                List<SoulQuestion> soulQuestionList = soulQuestionService.findByQuestionnaireId(questionnaire.getId());

                if (CollectionUtil.isNotEmpty(soulQuestionList)) {
                    for (SoulQuestion soulQuestion : soulQuestionList) {
                        SoulQuestionVo soulQuestionVo = new SoulQuestionVo();
                        //存放所有选项
                        List<SoulQuestionOptionVo> soulQuestionOptionVos = new ArrayList<>();
                        //根据问题的id查找选项
                        List<SoulQuestionOption> soulQuestionOptionList = soulQuestionOptionService.findByQuestionId(soulQuestion.getId());
                        if (CollectionUtil.isNotEmpty(soulQuestionOptionList)) {
                            for (SoulQuestionOption soulQuestionOption : soulQuestionOptionList) {
                                SoulQuestionOptionVo soulQuestionOptionVo = new SoulQuestionOptionVo();
                                soulQuestionOptionVo.setId(soulQuestionOption.getId().toString());
                                soulQuestionOptionVo.setOption(soulQuestionOption.getContent());
                                soulQuestionOptionVos.add(soulQuestionOptionVo);
                            }
                        }
                        //将问题和选项集合转移到SoulQuestionVo

                        soulQuestionVo.setId(soulQuestion.getId().toString());
                        soulQuestionVo.setQuestion(soulQuestion.getStem());
                        soulQuestionVo.setOptions(soulQuestionOptionVos);
                        questions.add(soulQuestionVo);
                    }
                }


                //查找是否锁定 通过用户id和问卷id查找
                QuestionUserLock questionUserLock = questionUserLockService.findByUserIdAndQuestionnaireId(userId, questionnaire.getId());
                if (questionUserLock != null) {
                    questionnaireVo.setIsLock(questionUserLock.getIsLock());
                } else {
                    if (questionnaire.getId() == 1) {
                        questionnaireVo.setIsLock(0);
                    } else {
                        questionnaireVo.setIsLock(1);
                    }
                }
                //查看是否有报告
                QuestionnaireReport questionnaireReport = questionnaireReportService.findByUserId(userId, questionnaire.getId());
                if (questionnaireReport != null) {
                    questionnaireVo.setReportId(questionnaireReport.getId().toString());
                }
                BeanUtil.copyProperties(questionnaire, questionnaireVo);

                questionnaireVo.setLevel(questionnaire.getLevel().toString());
                questionnaireVo.setId(questionnaire.getId().toString());

                questionnaireVo.setQuestions(questions);
                questionnaireVos.add(questionnaireVo);
            }
        }

        return questionnaireVos;

    }


    @Reference
    private QuestionnaireResultService questionnaireResultService;

    //测灵魂-提交问卷
    public String saveTestSoul(List<Answers> answers) {
        Long score = 0L;
        for (Answers answer : answers) {
            Long questionId = Long.valueOf(answer.getQuestionId());
            Long optionId = Long.valueOf(answer.getOptionId());
            SoulQuestionOption soulQuestionOption = soulQuestionOptionService.findScore(questionId, optionId);
            score = score + Long.valueOf(soulQuestionOption.getScore());
        }
        Long questionId = Long.valueOf(answers.get(0).getQuestionId());
        SoulQuestion soulQuestion = soulQuestionService.findByQuestionId(questionId);


        QuestionnaireResult questionnaireResult = questionnaireResultService.findByScore(score, soulQuestion.getQuestionnaireId());

        QuestionnaireReport questionnaireReport = new QuestionnaireReport();
        questionnaireReport.setUserId(UserHolder.getId());
        questionnaireReport.setResultId(questionnaireResult.getId());

        questionnaireReport.setExtroversion("85%");
        questionnaireReport.setJudgement("70%");
        questionnaireReport.setAbstraction("88%");
        questionnaireReport.setRationality("60%");
        questionnaireReport.setQuestionnaireId(questionnaireResult.getQuestionnaireId());

        Long id = questionnaireReportService.save(questionnaireReport);

        //在tb_question_user_lock保存问卷解锁信息
        QuestionUserLock questionUserLock = new QuestionUserLock();
        if (questionnaireResult.getQuestionnaireId() != 3) {
            questionUserLock.setIsLock(0);
            questionUserLock.setQuestionnaireId(questionnaireResult.getQuestionnaireId() + 1);
            questionUserLock.setUserId(UserHolder.getId());
            questionUserLockService.save(questionUserLock);
        }
        return id.toString();
    }

    //测灵魂-查看结果
    public TestResultVo findResult(Long id) {
        QuestionnaireReport questionnaireReport = questionnaireReportService.findById(id);
        QuestionnaireResult questionnaireResult = questionnaireResultService.findByResultId(questionnaireReport.getResultId());
        TestResultVo testResultVo = new TestResultVo();
        testResultVo.setConclusion(questionnaireResult.getContent());
        testResultVo.setCover(questionnaireResult.getCover());
        List<Dimensions> dimensions = new ArrayList<>();

        Dimensions dimensions1 = new Dimensions();
        dimensions1.setKey("外向");
        dimensions1.setValue(questionnaireReport.getExtroversion());
        dimensions.add(dimensions1);

        Dimensions dimensions2 = new Dimensions();
        dimensions2.setKey("判断");
        dimensions2.setValue(questionnaireReport.getJudgement());
        dimensions.add(dimensions2);

        Dimensions dimensions3 = new Dimensions();
        dimensions3.setKey("抽象");
        dimensions3.setValue(questionnaireReport.getAbstraction());
        dimensions.add(dimensions3);

        Dimensions dimensions4 = new Dimensions();
        dimensions4.setKey("理性");
        dimensions4.setValue(questionnaireReport.getRationality());
        dimensions.add(dimensions4);

        List<SimilarYou> similarYou = new ArrayList<>();

        List<QuestionnaireReport> questionnaireReportList = questionnaireReportService.findByResultId(questionnaireReport.getResultId());
        if (CollectionUtil.isNotEmpty(questionnaireReportList)) {
            for (QuestionnaireReport report : questionnaireReportList) {
                SimilarYou similarYou1 = new SimilarYou();
                UserInfo userInfo = userInfoService.findById(report.getUserId());
                if (userInfo.getId() == UserHolder.getId()) {
                    continue;
                }
                BeanUtil.copyProperties(userInfo,similarYou1);
                similarYou.add(similarYou1);
            }
        }

        testResultVo.setDimensions(dimensions);
        testResultVo.setSimilarYou(similarYou);

        return testResultVo;
    }



    @Autowired
    private FastFileStorageClient fileStorageClient;  // 存储客户端

    @Autowired
    private FdfsWebServer fdfsWebServer;  // tracker客户端

    @Reference
    private SoundService soundService;

    /**
     * 桃花传音---发送语音：
     * @param soundFile
     */
    public void saveVoice(MultipartFile soundFile) throws IOException {

        // 1. 保存语音---fastDFS
        StorePath storePath = fileStorageClient.uploadFile(soundFile.getInputStream(), soundFile.getSize(), FileUtil.extName(soundFile.getOriginalFilename()), null);
        // 拼接文件路径
        String soundUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();  // 拼接文件路径
        System.err.println("====>>>" + soundUrl);
        // 3. 构建Video对象
        Sound sound = new Sound();
        sound.setUserId(UserHolder.getId());  // 当前用户id
        sound.setSoundUrl(soundUrl);  // 声音文件路径地址
        sound.setId(ObjectId.get());
        sound.setCreated(System.currentTimeMillis());  // 创建时间
        sound.setPublishId(UserHolder.getId());
        // 4. 保存数据
        soundService.saveSound(sound);
    }


    /**
     * 桃花传音---接收语音：
     * @return
     */
    public SoundVo receiveVoice() {

        // 1. 获取当前用户id
        Long loginUserId = UserHolder.getId();

        // 2. 查询出所有音频文件
        List<Sound> soundList = soundService.receiveSound();

        SoundVo soundVo = new SoundVo();

        // 3. 判空
        if (CollectionUtil.isNotEmpty(soundList)) {

            //设置初始剩余次数为0
            Integer count = 0;
            //判断Redis中剩余次数是否存在
            if (!stringRedisTemplate.hasKey("SoundCount_" + loginUserId)) {
                //如果不存在设置Redis中剩余次数为8,过期时间为一天结束至当前系统时间
                stringRedisTemplate.opsForValue().set("SoundCount_" + loginUserId, "8", Duration.ofDays(1));
                count = 8;
            }else {
                //如果Redis中剩余次数存在，获取Redis
                String value = stringRedisTemplate.opsForValue().get("SoundCount_" + loginUserId);
                if (Integer.valueOf(value) > 0) {
                    //剩余次数-1
                    count = Integer.valueOf(value) - 1;
                    //重新设置Redis中剩余次数,过期时间为一天结束至当前系统时间
                    stringRedisTemplate.opsForValue().set("SoundCount_" + loginUserId, String.valueOf(count), Duration.ofDays(1));
                } else {
                    return null;
                }
            }

            // 随机获取一个语音
            Sound sound = soundList.get(RandomUtil.randomInt(0, soundList.size()));
            // 查询发布音频的用户详情
            UserInfo userInfo = userInfoService.findById(sound.getPublishId());
            // 封装SoundVo对象
            soundVo.setUserInfo(userInfo);
            soundVo.setSoundUrl(sound.getSoundUrl());
            soundVo.setRemainingTimes(count);
        }
        return soundVo;
    }

}
